#ifndef __CASOCKH__
#define __CASOCKH__


#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define KSOCK_TYPE_TCP 0
#define KSOCK_TYPE_UDP 1
#define KSOCK_TYPE_UNIX 2

typedef enum
{
	SOCK_STATUS_DISCONNECTED = 0,
	SOCK_STATUS_CONNECTING,
	SOCK_STATUS_CONNECTED,
	SOCK_STATUS_LISTENING,
} KSOCK_STATUS_E;

typedef enum
{
	SOCK_EVENT_CONNECTED=1<<0,
	SOCK_EVENT_DISCONNECTED=1<<1,
	SOCK_EVENT_READ=1<<2,
	SOCK_EVENT_WRITE=1<<3,
	SOCK_EVENT_INCOMING_ACCEPT=1<<4,
} KSOCK_EVENT_E;


typedef struct sock_t
{
	es_t* psys;
	int fd;
	int status;
	int sock_type;
	evt_t* pevt;
	int (*sockcb)(sock_t* psock, int events);
	union {
		void* user;
		int udata;
	};
	uint32_t remote_ip;
	uint16_t remote_port;
} sock_t;

typedef int (*SOCKCB)(sock_t* psock, int events);

int es_sock_open(es_t* psys, sock_t* psock, int stype, SOCKCB cb, void* user);
void es_sock_close(sock_t* psock);
int es_tcp_open(es_t* psys, sock_t* psock, SOCKCB cb, void* user);
int es_connect(sock_t* psock, char* ipaddr, int port);
int es_connect(sock_t* psock, uint32_t ip, int port);
int es_sock_listen(sock_t* psock, char* ipaddr, int port);
void es_tcp_close(sock_t* psock);
int es_read(sock_t* psock, void* buf, size_t size);
int es_write(sock_t* psock, void* buf, size_t size);
int es_tcp_listen(sock_t* psock, char* ipaddr, int port);
int es_tcp_accept(sock_t* plisten, sock_t* psock, SOCKCB cb, void* user);
void es_tcp_reject(sock_t* plisten);
int es_set_sock_event(sock_t* psock, int events);


#endif
